﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using arthuraafn_xna_3d.Base;


namespace arthuraafn_xna_3d
{
    class Ship: GameObject3D 
    {
        private static float OFFSET_BACK = 20.0f;
        private static float OFFSET_UP = 5.0f;
        private static float OFFSET_LEFT = 0.0f;
        private static float OFFSET_TARGET_UP = 0.0f;
        private static float OFFSET_TARGET_LEFT = -1.0f;
        private static float ANGLE_FACTOR = 0.02f;
        private static float FOLLOW_SPEED = 1.0f;
        private static float MIN_DISTANCE = 1.0F;

        private static float SPEED_ACC = 1.02f;
        private static float SPEED_MIN = 0.05f;
        private static float SPEED_MAX = 1.0f;
        private static float FRICTION = 0.995f;

        private float speedforward;

        public Ship(Game game, BasicCamera camera):base(game,camera, GetModel(game))
        {
            this.Scale = 0.05f;
            //this.Scale = 1.0f;

            Position = Vector3.Backward;

            UpdateWorld();

            UpdateCamera();
        }

        public override void Update(GameTime gameTime)
        {
         
            UpdateInput();

            base.Update(gameTime);

            UpdatePosition();

            UpdateCamera();

        }

        private void UpdatePosition()
        {
            
            if (speedforward > SPEED_MIN )
            {
                if (speedforward > SPEED_MAX) 
                    speedforward = SPEED_MAX;
                Vector3 forward = this.world.Forward;
                forward.Normalize();
                this.Position += forward * speedforward;
                UpdateWorld();
            }
            else
            {
                speedforward = 0.0f;
            }
            speedforward *= FRICTION;
        }

        private void UpdateCamera()
        {
            Vector3 back = this.world.Backward;

            Vector3 up = this.world.Up;

            Vector3 left = this.world.Left;

            back.Normalize();

            up.Normalize();

            left.Normalize();

            Vector3 targetcamera = this.Position + (left * OFFSET_TARGET_LEFT ) + ( up * OFFSET_TARGET_UP);

            Vector3 bestPosition = this.Position;
            Vector3 cameraPos = camera.Position;

            bestPosition += back * OFFSET_BACK;
            bestPosition += up * OFFSET_UP;
            bestPosition += left * OFFSET_LEFT;
            float dist = Vector3.Distance(cameraPos , bestPosition);

            if (dist > MIN_DISTANCE )
            {
                Vector3 direction = cameraPos - bestPosition;
                direction.Normalize();
                cameraPos -= direction * FOLLOW_SPEED;
            }
            else
            {
                cameraPos = bestPosition;
            }

            camera.LookAt(cameraPos, targetcamera, Vector3.Up);

        }

        private void UpdateInput()
        {
            var input = (IInputService)Game.Services.GetService(typeof(IInputService));

            //Point mousevar = input.MouseCenterDiff();

            //RotationYDegrees += ( mousevar.X * ANGLE_FACTOR );
           // RotationXDegrees += ( mousevar.Y * ANGLE_FACTOR );

            if (input.teclado.IsKeyDown(Keys.W))
            {
                if (speedforward < SPEED_MIN) speedforward = SPEED_MIN;
                speedforward *= SPEED_ACC;
            }
        }

        #region funcoes estáticas

        protected static Model GetModel(Game game) 
        {
            return game.Content.Load<Model>("Models/Ship/wasphunter");
        }

        #endregion

        #region Propriedades


        #endregion

    }

}
